﻿using System;
using RpcClient;
using RpcHelper;
using RpcModel;
using Wedonek.RpcStore.Gateway.Interface;
using Wedonek.RpcStore.Gateway.Model;
using Wedonek.RpcStore.Service.Interface;
using Wedonek.RpcStore.Service.Model;

namespace Wedonek.RpcStore.Gateway.Service
{
    internal class ResourceShieldService : IResourceShieldService
    {
        private readonly IResourceShieldCollect _ShieId;
        private readonly IRpcMerCollect _RpcMer;
        private readonly IServerCollect _Server;
        private readonly IServerTypeCollect _ServerType;
        public ResourceShieldService(IResourceShieldCollect shield,
            IRpcMerCollect rpcMer,
            IServerCollect server,
            IServerTypeCollect serverType)
        {
            this._Server = server;
            this._RpcMer = rpcMer;
            this._ServerType = serverType;
            this._ShieId = shield;
        }

        public void Delete(long id)
        {
            ResourceShield shield = this._ShieId.Get(id);
            this._ShieId.Delete(shield);
        }
        public DateTime? GetBeOverTime(long id)
        {
            ResourceShield shield = this._ShieId.Get(id);
            return shield.BeOverdueTime == 0 ? null : shield.BeOverdueTime.ToDateTime();
        }
        public void SetBeOverTime(long id, DateTime? overTime)
        {
            ResourceShield shield = this._ShieId.Get(id);
            this._ShieId.SetBeOverdueTime(shield, overTime);
        }
        public ShieldDatum[] Query(ShieIdQueryParam query, IBasicPage paging, out long count)
        {
            ResourceShield[] shields = this._ShieId.Query(query, paging, out count);
            if (shields.Length == 0)
            {
                return null;
            }
            BasicRpcMer[] mers = this._RpcMer.GetBasic(shields.ConvertAll(a => a.RpcMerId));
            BasicServerType[] serverTypes = this._ServerType.GetBasic(shields.ConvertAll(a => a.SystemType));
            BasicService[] services = this._Server.GetBasic(shields.Convert(c => c.ServerId != 0, c => c.ServerId));
            return shields.ConvertMap<ResourceShield, ShieldDatum>((a, b) =>
            {
                b.RpcMer = mers.Find(c => c.Id == a.RpcMerId, c => c.SystemName);
                b.SystemType = serverTypes.Find(c => c.TypeVal == a.SystemType, c => c.SystemName);
                if (a.ServerId != 0)
                {
                    b.Server = services.Find(c => c.Id == a.ServerId, c => c.ServerName);
                }
                b.ApiVer = a.ApiVerNum.FormatVerNum();
                return b;
            });

        }
        public long Add(ShieIdSetParam param)
        {
            ResourceShield add = param.ConvertMap<ShieIdSetParam, ResourceShield>();
            add.ShieKey = string.Join('_', param.RpcMerId, param.SystemType, param.ServerId, param.ApiVerNum);
            if (param.ServerId != 0 && !param.ApiVerNum.IsNull())
            {
                add.SortNum = 4;
            }
            else if (param.ServerId == 0 && !param.ApiVerNum.IsNull())
            {
                add.SortNum = 2;
            }
            else if (param.ServerId != 0 && param.ApiVerNum.IsNull())
            {
                add.SortNum = 3;
            }
            else
            {
                add.SortNum = 1;
            }
            return this._ShieId.Add(add);
        }
    }
}
